package XmlHash;
use strict;

our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);

use Exporter ();
@ISA = qw(Exporter);
@EXPORT = qw(xml2hash hash2xml readxml2hash);

$VERSION = '1.0';

use Data::Dumper;

# except way to the file with xml code
#return hash from xml
sub xml2hash { 
    my %HASH;
    tag2hash(file2txt(shift),\%HASH);
    return \%HASH;
}

#except hash with structure xml
#return the same hash with values
sub readxml2hash {
    my $hash = shift;
    my $file = shift;
    my $txt = file2txt($file);
    read2hash($hash,$txt);
}  

sub tag2hash {
    my ($s,$h) = @_;
    while ($s =~ /<(\w+)>(.+)<\/\1>/g) {
	my ($key,$val) = ($1,$2);
	if ($val =~ /</) {
    	    $h->{$key} = {};
	    tag2hash($val,$h->{$key});
	} else {
	    $h->{$key} = $val;
	}
    }
}

sub read2hash {
    my ($hash,$txt) = @_;
    foreach my $key (keys %$hash) {
	$txt =~ /<$key>(.+?)<\/$key>/;
	my $intxt = $1;
	if ( ref($$hash{$key}) eq "HASH" ) {
	    read2hash($$hash{$key},$intxt);
	} else {
	    $$hash{$key} = $intxt;
	}
	
    }
    $hash;
}

sub file2txt {
    my $file = shift;
    open (F,$file) or print STDERR "couldn't open $file: $!\n";
    local $/ = undef;    
    my $txt = <F>;
    close F;
    
    $txt =~ s/\x0D?\x0A//g;# remove end of line
    $txt =~ s/\s+|#.*?#//g; # remove empty line, blank, tab and commentary
    $txt;
}

my $file;
my $i = -1;
#except hash with structure of xml code and file to print;
my $XML;
sub hash2xml {
	my $HASH = shift;
	$XML = "<xmlbody>\n";
	val2tag($HASH);
	$XML .= "</xmlbody>\n";
	#warn $XML;
	return $XML;
}

sub val2tag {
#     $i++;
    my $h = shift;
	#warn Dumper($h);
    foreach my $key (sort keys %$h) {
		if ( ref($h->{$key}) eq "HASH" ) {
	    	$XML .= "<$key>\n";
	    	val2tag($h->{$key});
	    	$XML .= "</$key>\n";
		} elsif ( ref($h->{$key}) eq "ARRAY" ) {
			foreach my $ai( @{$h->{$key}} ) {
				$XML .= "<$key>\n";
				if ( ref($ai) ) { val2tag($ai); }
				else {$XML .= $ai."\n";}
				$XML .= "</$key>\n"
			}
		} else {
	    	$XML .= "<$key>$h->{$key}</$key>\n";
		}
    }
#     $i--;
}

sub printtab {
    my ($j,$txt) = @_;
    open (F, ">>$file") or print STDERR "couldn't open $file: $!\n";
    print F "	"x$j.$txt."\n";
    close F;
}

1;
